﻿// -----------------------------------------------------------------------
//  <copyright file="StoreService.StockingLog.cs" company="柳柳软件">
//      Copyright (c) 2014-2015 66SOFT. All rights reserved.
//  </copyright>
//  <site>http://www.66soft.net</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2015-12-07 18:05</last-date>
// -----------------------------------------------------------------------

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

using OSharp.Core.Mapping;
using OSharp.Utility;
using OSharp.Utility.Data;

using ZH.JY.Store.Dtos;
using ZH.JY.Store.Models;


namespace ZH.JY.Store
{
    partial class StoreService
    {
        #region Implementation of IStoreContract

        /// <summary>
        /// 获取 入库记录信息查询数据集
        /// </summary>
        public IQueryable<StockingLog> StockingLogs
        {
            get { return StockingLogRepository.Entities; }
        }

        /// <summary>
        /// 检查入库记录信息信息是否存在
        /// </summary>
        /// <param name="predicate">检查谓语表达式</param>
        /// <param name="id">更新的入库记录信息编号</param>
        /// <returns>入库记录信息是否存在</returns>
        public Task<bool> CheckStockingLogExists(Expression<Func<StockingLog, bool>> predicate, int id = 0)
        {
            predicate.CheckNotNull("predicate");
            return StockingLogRepository.CheckExistsAsync(predicate, id);
        }

        /// <summary>
        /// 添加入库记录信息信息
        /// </summary>
        /// <param name="dtos">要添加的入库记录信息DTO信息</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> CreateStockingLogs(params StockingLogInputDto[] dtos)
        {
            dtos.CheckNotNull("dtos");
            if (dtos.Length != 1)
            {
                return new OperationResult(OperationResultType.Error, "无法一次新增多个入库信息");
            }
            StockingLogInputDto dto = dtos[0];
            if (dto.Count <= 0)
            {
                return new OperationResult(OperationResultType.Error, "产品入库数量必须大于0");
            }
            StockingLogRepository.UnitOfWork.TransactionEnabled = true;
            StockingLog stocking = dto.MapTo<StockingLog>();
            Product product = await ProductRepository.GetByKeyAsync(dto.ProductId);
            if (product == null)
            {
                return new OperationResult(OperationResultType.Error, "指定编号的商品信息不存在");
            }
            product.Count += stocking.Count;
            stocking.Product = product;
            await StockingLogRepository.InsertAsync(stocking);
            await ProductRepository.UpdateAsync(product);

            return await StockingLogRepository.UnitOfWork.SaveChangesAsync() > 0
                ? new OperationResult(OperationResultType.Success, $"{dto.Count} 个商品“{product.Name}”入库成功，当前库存总数为 {product.Count}")
                : OperationResult.NoChanged;
        }

        /// <summary>
        /// 更新入库记录信息信息
        /// </summary>
        /// <param name="dtos">包含更新信息的入库记录信息DTO信息</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> UpdateStockingLogs(params StockingLogInputDto[] dtos)
        {
            dtos.CheckNotNull("dtos" );
            if (dtos.Length != 1)
            {
                return new OperationResult(OperationResultType.Error, "无法一次编辑多个入库信息");
            }
            StockingLogInputDto dto = dtos[0];
            if (dto.Count <= 0)
            {
                return new OperationResult(OperationResultType.Error, "产品入库数量必须大于0");
            }
            StockingLogRepository.UnitOfWork.TransactionEnabled = true;
            StockingLog stocking = await StockingLogRepository.GetByKeyAsync(dto.Id);
            Product product = await ProductRepository.GetByKeyAsync(dto.ProductId);
            if (product == null)
            {
                return new OperationResult(OperationResultType.Error, "指定编号的商品信息不存在");
            }
            if (product.Id == dto.ProductId)
            {
                int count = dto.Count - stocking.Count;
                stocking.Count = dto.Count;
                product.Count += count;
                await StockingLogRepository.UpdateAsync(stocking);
                await ProductRepository.UpdateAsync(product);
            }
            else
            {
                Product oldProduct = stocking.Product;
                oldProduct.Count -= stocking.Count;
                product.Count += dto.Count;
                stocking.Product = product;
                await StockingLogRepository.UpdateAsync(stocking);
                await ProductRepository.UpdateAsync(oldProduct);
                await ProductRepository.UpdateAsync(product);
            }
            return await StockingLogRepository.UnitOfWork.SaveChangesAsync() > 0
                ? new OperationResult(OperationResultType.Success, "商品入库信息更新成功")
                : OperationResult.NoChanged;
        }

        /// <summary>
        /// 删除入库记录信息信息
        /// </summary>
        /// <param name="ids">要删除的入库记录信息编号</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> DeleteStockingLogs(params int[] ids)
        {
            ids.CheckNotNull("ids" );
            if (ids.Length != 1)
            {
                return new OperationResult(OperationResultType.Error, "无法一次删除多个入库信息");
            }
            int id = ids[0];
            StockingLogRepository.UnitOfWork.TransactionEnabled = true;
            StockingLog stocking = await StockingLogRepository.GetByKeyAsync(id);
            Product product = stocking.Product;
            product.Count -= stocking.Count;
            await StockingLogRepository.DeleteAsync(stocking);
            await ProductRepository.UpdateAsync(product);
            return await StockingLogRepository.UnitOfWork.SaveChangesAsync() > 0
                ? new OperationResult(OperationResultType.Success, $"{stocking.Count} 个商品“{product.Name}”入库信息删除成功，当前库存总数为：{product.Count}")
                : OperationResult.NoChanged;
        }

        #endregion
    }
}